/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2008，所有权利保留。
 * 
 * 文件名：	DependencyAnalyzer.java
 * 模块说明：	
 * 修改历史：
 * Jan 8, 2008 - zhangyanbo - 创建。
 */
package com.hd123.rumba.upgrade.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.hd123.rumba.exception.BusinessException;

/**
 * @author zhangyanbo
 * 
 */
public class DependencyAnalyzer implements IDependencyAnalyzer {

  private HashMap<String, List<String>> depends = new HashMap<String, List<String>>();

  public void addDependency(String currentId, String dependId) throws Exception {
    if (currentId == null)
      throw new Exception("传入的参数currentId不能为空。");
    List<String> dependIds = depends.get(currentId);
    if (dependIds == null) {
      dependIds = new ArrayList<String>();
      depends.put(currentId, dependIds);
    }
    if (dependId != null) {
      if (!dependIds.contains(dependId))
        dependIds.add(dependId);
      if (depends.get(dependId) == null)
        depends.put(dependId, new ArrayList<String>());
    }
  }

  public List<String> getSortedIds() throws Exception {
    HashMap<String, List<String>> works = new HashMap<String, List<String>>();
    works.putAll(depends);
    List<String> nodeIds = new ArrayList<String>();
    nodeIds.addAll(works.keySet());
    // 分析
    List<String> sortedIds = new ArrayList<String>();
    while (nodeIds.size() > 0) {
      int lastSize = nodeIds.size();
      int idx = 0;
      while (idx < nodeIds.size()) {
        String nodeId = nodeIds.get(idx);
        List<String> dependIds = works.get(nodeId);
        if (dependIds.size() == 0) {
          nodeIds.remove(nodeId);
          works.remove(nodeId);
          sortedIds.add(nodeId);
          // 删除依赖关系
          for (String id : nodeIds) {
            List<String> ids = works.get(id);
            if (ids.contains(nodeId))
              ids.remove(nodeId);
          }
        }
        idx++;
      }
      if (lastSize == nodeIds.size())
        throw new BusinessException("分析依赖关系失败，存在循环依赖。");
    }
    return sortedIds;
  }

}
